<template>
  <div class="zui-image-uploader" :class="{ disabled }">
    <ul class="images">
      <li v-for="(url, idx) in imageUrls" :key="idx" class="image-wrap clickable" @click="onImageClick(idx)">
        <img class="image" :src="url" />
        <div class="tags-wrap">
          <ul v-if="images[idx]['tags']" class="tags">
            <li v-for="(tag, tagIdx) in images[idx]['tags']" :key="tagIdx">{{ tag }}</li>
          </ul>
          <zui-loading v-if="images[idx]['loading']" class="loading" position="inline" size="xsmall" />
        </div>

        <span v-if="!readonly && editActions.includes('remove')" class="remove-wrap">
          <i class="remove iconfont-zui icon-zui-x clickable" @click.stop="onRemoveClick(idx)"></i>
        </span>
      </li>

      <li
        v-if="!readonly && imageUrls.length < max && editActions.includes('add')"
        class="image-wrap add-btn"
        :class="{ loading: loading }"
        @click="!loading && onAddClick()"
      >
        <div v-if="!loading" class="icon iconfont-zui icon-zui-camera"></div>
        <zui-loading v-else class="loading" position="inline" size="xsmall" />
      </li>
    </ul>
    <div v-if="readonly && !images.length" class="empty">未上传</div>
  </div>
</template>

<script setup>
import { ref, watch, computed } from 'vue'
import ZuiLoading from '../loading/ZuiLoading.vue'

const emit = defineEmits(['update:modelValue', 'addClick', 'imageClick', 'remove'])

const props = defineProps({
  modelValue: { type: Array, default: [] },
  disabled: Boolean,
  readonly: Boolean,
  loading: Boolean,
  padding: { type: String, default: '16px 20px' },
  /**
   * 可执行操作 add：增加，remove：移除
   */
  editActions: { type: Array, default: ['add', 'remove'] },
  max: {
    type: Number,
    default: 9
  }
})

const images = ref()
const imageUrls = computed(() => {
  return images.value.map((item) => item.url)
})

watch(images, (val) => [emit('update:modelValue', val)])
watch(
  () => props.modelValue,
  (val) => {
    images.value = val
  },
  {
    immediate: true
  }
)

//***** 上传 *****/
async function onAddClick() {
  emit('addClick')
}

//***** 移除 *****/
function onRemoveClick(idx) {
  emit('remove', idx)
}

//***** 预览 *****/
function onImageClick(idx) {
  emit('imageClick', idx)
}
</script>

<style lang="scss" scoped>
.zui-image-uploader {
  width: 100%;
  box-sizing: border-box;
  &.disabled {
    opacity: 0.5;
  }
  .images {
    text-align: left;
    margin: -8px 0 0 -8px;

    .image-wrap {
      display: inline-block;
      position: relative;
      margin-left: 8px;
      margin-top: 8px;
      width: 64px;
      height: 64px;
      background-color: var(--zui-color-background);
      border-radius: var(--zui-size-border-radius-small);

      .image {
        object-fit: cover;
        width: 100%;
        height: 100%;
        border-radius: var(--zui-size-border-radius-small);
      }
      .tags-wrap {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        border-radius: var(--size-border-radius-small);
        overflow: hidden;
        .tags {
          position: absolute;
          bottom: 0;
          left: 0;
          right: 0;
          padding: 4px 0;
          font-size: var(--zui-size-text-small);
          line-height: 1.2em;
          color: #ffffff;
          text-align: center;
          background-color: rgba(0, 0, 0, 0.5);
        }
      }

      .remove-wrap {
        display: block;
        position: absolute;
        top: -8px;
        right: -8px;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        box-shadow: var(--zui-box-shadow);
        background-color: #ffffff;
        .remove {
          width: 16px;
          height: 16px;
          line-height: 16px;
          text-align: center;
          background-color: var(--zui-color-text-secondary);
          border-radius: 50%;
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translateX(-50%) translateY(-50%);
          font-size: var(--zui-size-text-xsmall);
          color: #ffffff;
        }
      }

      &.add-btn {
        position: relative;
        .icon {
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translateX(-50%) translateY(-50%);
          color: var(--zui-color-text-secondary);
          font-size: 32px;
        }
        &.loading {
          cursor: not-allowed;
          .loading {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translateX(-50%) translateY(-50%);
          }
        }
      }
    }
  }
  .empty {
    margin-top: 8px;
    border-radius: var(--zui-size-border-radius-small);
    line-height: var(--zui-size-line-height-regular);
    padding: 6px 12px;
    background-color: var(--zui-color-fill-light);
    color: var(--zui-color-text-secondary);
  }
}
</style>
